﻿#include "printerManager.h"


// Provider =========================================

PrintPreviewProvider::PrintPreviewProvider() : QQuickImageProvider(QQuickImageProvider::Image)
{
}

QImage PrintPreviewProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize){
    return *pm;
}


// PrinterManager ===================================


PrinterManager::PrinterManager()
{
    image = new QImage(BW, BH, QImage::Format_RGB888);
    image->fill(QColor(Qt::white));
    image_chrom = new QImage();

    font1 = QFont("宋体", 9);
    font1.setBold(true);
    font2 = QFont("宋体", 9);
    font2.setBold(false);

}


PrinterManager& PrinterManager::I(){
    static PrinterManager instance;
    return instance;
}

void PrinterManager::initProvider(QQmlApplicationEngine *engine){

    provider = new PrintPreviewProvider();
    provider->pm = image;
    engine->addImageProvider(QLatin1String("printPreviewImage"), provider);

    provider_chrom = new PrintPreviewProvider();
    provider_chrom->pm = image_chrom;
    engine->addImageProvider(QLatin1String("chromImage"), provider_chrom);

}

QStringList PrinterManager::getPrinterList(){
    auto res = QPrinterInfo::availablePrinterNames();
    return res;
}



void PrinterManager::print(QString printerName){
    qDebug() << "打印信息" << printerName;
    QPrinter printer(QPrinter::ScreenResolution);
    printer.setPrinterName(printerName);

    QString htmlText = generateHTML();
    QTextDocument td;
    td.setHtml(htmlText);
    td.print(&printer);

    qDebug() << "打印完成";

}

int PrinterManager::printExcel(QString filePath){

    __LOG_FSTART(filePath);


    // 参考 https://blog.csdn.net/qq_22328661/article/details/96320875

    filePath = filePath.replace("-","_").replace(" ","_").replace(":","_");

    QFile file(filePath);
    if(!file.exists()){
        __LOG_FEND(-1);             // 打印文件缺失
        return -1;
    }

    QAxObject* pApplication;
    QAxObject* pWorkBooks = NULL;
    QAxObject* pWorkBook = NULL;
    QAxObject* pSheets = NULL;
    QAxObject* pSheet = NULL;

    pApplication = new QAxObject();
    bool res = pApplication->setControl("Excel.Application");//连接Excel控件
    if(!res){ __LOG_FEND(-2);  return -2; }         // 调用Excel失败

    pApplication->dynamicCall("SetVisible(bool)", true);//false不显示窗体
    pApplication->setProperty("DisplayAlerts", false);//不显示任何警告信息。
//    pApplication->setProperty("ScreenUpdating",false);//直接显示打印预览不需要显sheet内容
    pWorkBooks = pApplication->querySubObject("Workbooks");
    pWorkBook = pWorkBooks->querySubObject("Open(const QString &)", QFileInfo(file).absolutePath() + "/" + QFileInfo(file).fileName());
    pSheets = pWorkBook->querySubObject("Sheets");//所有sheets
    pSheet = pSheets->querySubObject("Item(int)", 1);//第一个sheet

    //显示预览设置里的网格线（默认是没有网格线的）
//    pSheet->querySubObject("PageSetup")->setProperty("PrintGridlines",true);
    pSheet->querySubObject("PageSetup")->setProperty("FitToPagesWidth", 1);
    pSheet->querySubObject("PageSetup")->setProperty("FitToPagesTall", 1);

    //调出excel打印预览（此地方为阻塞状态，退出excel预览后，才执行下面的代码）
    pWorkBook->dynamicCall("PrintPreview");

    pWorkBooks->dynamicCall("Close(bool)",false);//关闭工作簿
    //关闭excel
    if (pApplication != NULL)
    {
        pApplication->dynamicCall("Quit()");
        delete pApplication;
        pApplication = NULL;
    }

    //删除文件
    QFile tempFile(filePath);
    if(tempFile.exists())
    {
        tempFile.remove();
    }

    __LOG_FEND(0);

    return 0;

}



void PrinterManager::refreshPreview(double dp){

    if(provider == nullptr){
        __LOG_ERROR("Provider=nullptr");
        return;
    }
    this->dp = dp;

    if(image) {delete image;}

    image = new QImage(std::floor(BW*dp), std::floor(BH*dp), QImage::Format_RGB888);
    image->fill(QColor(Qt::white));
    provider->pm = image;

    expInfo = ReportManager::I().getExperimentInfo();
    logInfo = ReportManager::I().getLogInfo();

    QPainter* painter = generatePainter();

    qDebug() << "dp" << dp << "size" << image->size();

    delete painter;
}

void PrinterManager::refreshReportInfo(){

    // 从excel里面读取实验信息和能谱图数据并返回
    expInfo = ReportManager::I().getExperimentInfo();
    logInfo = ReportManager::I().getLogInfo();
    QString expName = expInfo["ExpName"].toString();

    // 获取能谱图
    if(provider_chrom == nullptr){
        __LOG_ERROR("Provider=nullptr");
        return;
    }
    QXlsx::Document xlsx("./report/autoExport_" + expInfo["ExpStartTime"].toString().replace("-","_").replace(" ","_").replace(":","_") + ".xlsx");
    if(image_chrom == nullptr){
        image_chrom = new QImage();
    }
    if(xlsx.load()){
        bool res = xlsx.getImage(1, *(image_chrom));            // 啥玩意，乱七八糟的……
        provider_chrom->pm = image_chrom;
        qDebug() << "获取能谱图结果" << res;
    }else{
        qDebug() << "读取本地报告文件失败";
        image_chrom->fill(QColor(Qt::white));
    }
}

QVariantMap PrinterManager::getExpInfo(){
    return expInfo;
}
QVariantList PrinterManager::getLogInfo(){
    return logInfo;
}


QPainter* PrinterManager::generatePainter(){
    QPainter* painter = new QPainter(image);

    painterDrawExpInfo(painter);
    painterDrawExpLog(painter);

    return painter;
}


void PrinterManager::painterDrawExpLog(QPainter *painter){
    int mW = 80*dp;
    int mH = 80*dp;
    int W = BW*dp - 2*mW;
    int lineH = 35*dp;
    int H = lineH*5.2;

    painter->setPen(QColor(0, 0, 0));
    painter->drawText(QPoint(mW, mH-10*dp), "中国科学院大连化学物理研究所");
    QImage image_code(":/picture/tm.png");
    painter->drawImage(QRect(mW+W-100*dp, mH-40*dp, 100*dp, 40*dp), image_code);
    painter->setFont(font1);
    painter->drawText(QPoint(mW, mH+30*dp), "综合报告");
    painter->setFont(font2);
    painter->drawText(QPoint(mW+W-240, mH+30*dp), "打印时间: " + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"));

    painter->drawRect(mW, mH+40*dp, W, H);      // 外框矩形
    // ---- 第一列
    painter->drawText(QPoint(mW+8*dp, mH+62*dp+lineH*0), "名称");
    painter->drawText(QPoint(mW+8*dp, mH+62*dp+lineH*1), "实验日期");
    painter->drawText(QPoint(mW+8*dp, mH+62*dp+lineH*2), "描述");
    painter->drawText(QPoint(mW+8*dp, mH+62*dp+lineH*3), "实验名称");
    if(StaticProperties::softType!=1){
        painter->drawText(QPoint(mW+8*dp, mH+62*dp+lineH*4), "纯化耗材名称");
    }
    // ---- 第二列
    painter->drawText(QPoint(mW+8*dp+W/2, mH+62*dp+lineH*0), "设备名称");
    painter->drawText(QPoint(mW+8*dp+W/2, mH+62*dp+lineH*1), "操作人");
//    painter->drawText(QPoint(mW+8*dp+W/2, mH+62*dp+lineH*2), "");
    painter->drawText(QPoint(mW+8*dp+W/2, mH+62*dp+lineH*3), "实验类型");

    if(StaticProperties::softType!=1){
        painter->drawText(QPoint(mW+8*dp+W/2, mH+62*dp+lineH*4), "耗材编码");
    }

    painter->drawText(QPoint(mW+4*dp+W/4-14, mH+62*dp+lineH*0),   expInfo["ExpName"].value<QString>());
    painter->drawText(QPoint(mW+4*dp+W/4-14, mH+62*dp+lineH*1),   expInfo["ExpDate"].value<QString>());
    painter->drawText(QPoint(mW+4*dp+W/4-14, mH+62*dp+lineH*2),   expInfo["Memo"].value<QString>());
    painter->drawText(QPoint(mW+4*dp+W/4-14, mH+62*dp+lineH*3),   expInfo["ExpFlowName"].value<QString>());

    if(StaticProperties::softType!=1){
        painter->drawText(QPoint(mW+4*dp+W/4-14, mH+62*dp+lineH*4),   expInfo["ConsumableName"].value<QString>());
    }
    painter->drawText(QPoint(mW+4*dp+W/4*3-14, mH+62*dp+lineH*0), expInfo["EquName"].value<QString>());
    painter->drawText(QPoint(mW+4*dp+W/4*3-14, mH+62*dp+lineH*1), expInfo["Operator"].value<QString>());
//    painter->drawText(QPoint(mW+4*dp+W/4*3-14, mH+62*dp+lineH*2), expInfo["Operator"].value<QString>());
    painter->drawText(QPoint(mW+4*dp+W/4*3-14, mH+62*dp+lineH*3), expInfo["ExpType"].value<QString>());

    if(StaticProperties::softType!=1){
        painter->drawText(QPoint(mW+4*dp+W/4*3-14, mH+62*dp+lineH*4), expInfo["ConsumableCode"].value<QString>());
    }
    // 底下的 那个线
    // ---- 第一列
    painter->drawLine(QPoint(mW+W/4-14, mH+64*dp+lineH*0), QPoint(mW-8*dp+W/2, mH+64*dp+lineH*0));
    painter->drawLine(QPoint(mW+W/4-14, mH+64*dp+lineH*1), QPoint(mW-8*dp+W/2, mH+64*dp+lineH*1));
    painter->drawLine(QPoint(mW+W/4-14, mH+64*dp+lineH*2), QPoint(mW-8*dp+W, mH+64*dp+lineH*2));  // 第三行单元格合并
    painter->drawLine(QPoint(mW+W/4-14, mH+64*dp+lineH*3), QPoint(mW-8*dp+W/2, mH+64*dp+lineH*3));

    if(StaticProperties::softType!=1){
        painter->drawLine(QPoint(mW+W/4-14, mH+64*dp+lineH*4), QPoint(mW-8*dp+W/2, mH+64*dp+lineH*4));
    }
    // ---- 第二列
    painter->drawLine(QPoint(mW+W/4*3-14, mH+64*dp+lineH*0), QPoint(mW-8*dp+W, mH+64*dp+lineH*0));
    painter->drawLine(QPoint(mW+W/4*3-14, mH+64*dp+lineH*1), QPoint(mW-8*dp+W, mH+64*dp+lineH*1));
//    painter->drawLine(QPoint(mW+W/4*3-14, mH+64*dp+lineH*2), QPoint(mW-8*dp+W, mH+64*dp+lineH*2));
    painter->drawLine(QPoint(mW+W/4*3-14, mH+64*dp+lineH*3), QPoint(mW-8*dp+W, mH+64*dp+lineH*3));

    if(StaticProperties::softType!=1){
        painter->drawLine(QPoint(mW+W/4*3-14, mH+64*dp+lineH*4), QPoint(mW-8*dp+W, mH+64*dp+lineH*4));
    }


}

void PrinterManager::painterDrawExpInfo(QPainter *painter){

    int mW = 80*dp;
    int mH = 80*dp;
    int W = BW*dp - 2*mW;
    int lineH = 32*dp;

    painter->setFont(font1);
    painter->drawText(QPoint(mW, 330*dp), "实验步骤");
    painter->setFont(font2);
    painter->drawRect(mW, 340*dp, W, BH*dp-mH-340*dp);
    painter->drawText(QPoint(mW+8*dp+W*0.09, 365*dp+lineH*0), "时间");
    painter->drawText(QPoint(mW+8*dp+W*0.24, 365*dp+lineH*0), "步骤编号");
    painter->drawText(QPoint(mW+8*dp+W*0.55, 365*dp+lineH*0), "动作信息");
    painter->drawText(QPoint(mW+8*dp+W*0.79, 365*dp+lineH*0), "时间");
    painter->drawText(QPoint(mW+8*dp+W*0.89, 365*dp+lineH*0), "状态");

    int i = 1;
    foreach(QVariant line0, logInfo){

        int y = 380*dp + lineH*i;
        if(y < BH*dp-mH - 10*dp){


            QVariantList line1 = line0.value<QVariantList>();
            if(line1.size() < 4){
                qDebug() << "打印错误";
                continue;
            }
            QString info1 = line1[0].toString().split(" ").size() > 1 ? line1[0].toString().split(" ")[1] : line1[0].toString().split(" ")[0];  // 去掉时间的年月日;
            QString info2 = line1[1].toString();
            QString info3 = line1[2].toString();
            QString info4 = line1[3].toString();
            QString info5 = line1[4].toString();
            painter->drawText(QPoint(mW+8*dp+W*0.07, 365*dp+lineH*i), info1);
            painter->drawText(QPoint(mW+8*dp+W*0.28, 365*dp+lineH*i), info2);
            painter->drawText(QPoint(mW+8*dp+W*0.4,  365*dp+lineH*i), info3);
            painter->drawText(QPoint(mW+8*dp+W*0.79, 365*dp+lineH*i), info4);
            painter->drawText(QPoint(mW+8*dp+W*0.89, 365*dp+lineH*i), info5);
        }else{
            break;
        }
        i++;
    }

}


QString PrinterManager::generateHTML(){

    QString htmlText;

    // expInfo信息校验
//    for(int i = 0; i < 10; i ++){
//        if(expInfo.size() < i){
//            expInfo.push_back("");
//        }
//    }

    htmlText += QString("<div style='height: 30;'>中国科学院大学大连化学物理研究所</div>"
                        "<div style='width: %12;'>"
                        "<p><span style='font-weight: bold;'>综合报告</span><span style='float: right;'>（打印时间:%11）</span></p>"
                        "<table width=100% border=1 cellpadding=5 cellspacing=0 style='font-weight: normal;'>"
                        "<thead></thead>"
                        "<tbody><tr><th style='font-weight: normal; border: 0;'>名称</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%1</th>"
                        "<th style='font-weight: normal; border: 0;'>设备名称</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%2</th></tr>"
                        "<tr><th style='font-weight: normal; border: 0;'>试验日期</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%3</th>"
                        "<th style='font-weight: normal; border: 0;'>操作人</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%4</th></tr>"
                        "<tr><th style='font-weight: normal; border: 0;'>描述</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%5</th>"
                        "<th style='font-weight: normal; border: 0;'></th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%6</th></tr>"
                        "<tr><th style='font-weight: normal; border: 0;'>实验名称</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%7</th>"
                        "<th style='font-weight: normal; border: 0;'>实验类型</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%8</th></tr>"
                        "<tr><th style='font-weight: normal; border: 0;'>纯化耗材名称</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%9</th>"
                        "<th style='font-weight: normal; border: 0;'>耗材编码</th>"
                        "<th style='font-weight: normal; border-top: 0; border-left: 0; border-right: 0;'>%10</th></tr></tbody></table>"
                        "<p style='font-weight: bold;'>实验步骤</p>"
                        "<table width=100% border=1 cellpadding=5 cellspacing=0 style=''>"
                        "<tbody><tr><th style='font-weight: normal; border: 0;'>时间</th><th style='font-weight: normal; border: 0;'>步骤编号</th><th style='font-weight: normal; border: 0;'>动作信息</th><th style='font-weight: normal; border: 0;'>时间(ms)</th><th style='font-weight: normal; border: 0;'>状态</th></tr>")
            .arg(expInfo["ExpName"].toString(),
            expInfo["EquName"].toString(),
            expInfo["ExpDate"].toString(),
            expInfo["Operator"].toString(),
            expInfo["Memo"].toString(),
            expInfo[""].toString(),
            expInfo["ExpFlowName"].toString(),
            expInfo["ExpType"].toString(),
            expInfo["ConsumableName"].toString(),
            expInfo["ConsumableCode"].toString(),
            QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"), QString::number(600));

    foreach(QVariant line0, logInfo){
        QVariantList line1 = line0.value<QVariantList>();
        if(line1.size() < 5){
            qDebug() << "打印错误";
            continue;
        }
        QString info1 = line1[0].toString().split(" ").size() > 1 ? line1[0].toString().split(" ")[1] : line1[0].toString().split(" ")[0];
        QString info2 = line1[1].toString();
        QString info3 = line1[2].toString();
        QString info4 = line1[3].toString();
        QString info5 = line1[4].toString();
        htmlText += QString("<tr><th style='font-weight: normal; border: 0;'>%1</th><th style='font-weight: normal; border: 0;'>%2</th><th style='font-weight: normal; border: 0;'>%3</th><th style='font-weight: normal; border: 0;'>%4</th><th style='font-weight: normal; border: 0;'>%5</th></tr>")
                .arg(info1, info2, info3, info4, info5);
    }

    htmlText += "</tbody></table></div>";

    return htmlText;

}

